Groovy 是一種動態語言,可以用於開發完整的應用程式,但在 Gradle 中,我們主要將其用於管理套件和建置專案。以下我們將針對在 Java 中使用 Gradle 進行相依套件管理與專案建置時常用的語法進行說明。
Groovy 是一個動態類型語言
def
關鍵字定義變數。Groovy 會根據賦值自動推斷類型。
def projectName = "Quarkus App"
int version = 1
注意: 雖然 Groovy 是動態類型語言,但它與 Java 兼容,因此你仍然可以使用 Java 的強類型語法。
Groovy 中最強大的語法之一是閉包(Closure)。閉包是一段可執行的程式碼塊,可以在任意位置定義並傳遞作為參數。在 Gradle 中,閉包被廣泛用於配置區塊。
基本語法:
def greet = { name ->
println "Hello, $name"
}
greet("Quarkus")
Gradle中的閉包範例:
task hello {
doLast {
println 'Hello from Groovy Closure in Gradle!'
}
}
這裡的 doLast
就是一個閉包,它定義了在任務完成時需要執行的代碼。
對於閉包想更理解的話,可以參考我之前寫的文章 FP(Functional programming)簡易釐清 (含Currying 與 Closure 理解
Groovy 提供了簡化的集合處理方式,這對於在 Gradle 腳本中管理依賴列表或其他項目設定很有用。
範例:
def dependencies = ['quarkus-resteasy', 'quarkus-hibernate-orm']
dependencies.each { dep ->
println "Adding dependency: $dep"
}
def config = [name: 'Quarkus', version: '2.8.1']
println "Project ${config.name} version ${config.version}"
Groovy 允許簡單的字串插值,這在 Gradle 腳本中非常有用。例如,插入變數到字串中使用 $
符號。
範例:
def version = '1.0'
println "Building project version $version"
多行字串:Groovy 支援使用三引號('''
)來定義多行字串:
def description = '''
This is a multi-line
string in Groovy
'''
println description
Groovy 支援 Java 標準的 if-else
條件語句和各種迴圈,但它也提供了更簡潔的語法來進行條件判斷和迭代。
if (project.hasProperty('env')) {
println "Environment: ${project.env}"
} else {
println "No environment specified."
}
each
方法可以輕鬆遍歷列表:def tasks = ['compile', 'test', 'deploy']
tasks.each { task ->
println "Executing task: $task"
}
在 Groovy 中,使用 ?.
可以防止 NullPointerException
,如果左側變數為 null
,則整個表達式結果為 null
,不會引發錯誤。
範例:
def person = null
println person?.name // 不會引發 NullPointerException
Gradle 腳本實際上就是 Groovy 代碼。在 Gradle 中,幾乎所有構建腳本中的語法都是基於 Groovy 的 DSL 語法,例如:
apply plugin: 'java'
repositories { mavenCentral() }
dependencies { implementation 'io.quarkus:quarkus-resteasy' }
這些語法實際上就是 Groovy 的閉包結構。閉包允許你輕鬆定義並修改 Gradle 中的各種配置。
Gradle 主要是執行相關的 Groovy 程式,通過這些程式來下載 Maven 的套件或執行編譯相關的指令,以達到客製化與控管專案的套件與編譯執行。在 Gradle 專案中,主要有三個關鍵的設定檔案:gradle.properties
、settings.gradle
和 build.gradle
。讓我們逐一介紹它們的用途和常見設定:
gradle.properties
用於定義全局變數和屬性,主要用於定義可在多個腳本中重用的屬性。這對於大型專案中特別有用,因為它提供了一種集中管理變數的方式,避免在多個地方重複定義相同的值。
常見用途:
gradle.properties
提供了定義這些值的集中位置。# Plugin 版本管理
quarkusPluginId=io.quarkus
quarkusPluginVersion=2.8.1.Final
# 平台 BOM 定義
quarkusPlatformGroupId=io.quarkus.platform
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformVersion=2.8.1.Final
# 優化構建性能
org.gradle.daemon=true # 開啟 Gradle Daemon 加速構建
org.gradle.parallel=true # 允許並行構建
org.gradle.caching=true # 啟用構建緩存
這樣的設置文件可以在 build.gradle
中直接引用變數,如:
plugins {
id "${quarkusPluginId}" version "${quarkusPluginVersion}"
}
settings.gradle
文件是專案的入口點,用來定義專案的基本設置和結構。它負責告訴 Gradle 哪些模組(子專案)屬於該構建的一部分,並可配置依賴解析方式和套件管理。
常見用途:
include
語法來聲明專案中的各個子模組,使 Gradle 可以將它們納入構建流程。pluginManagement
區塊用來集中管理 Gradle 插件,包括定義套件的版本號和存儲庫位置,這有助於保持套件版本的一致性。// 定義根專案名稱
rootProject.name = 'my-quarkus-project'
// 定義子專案
include 'api', 'service', 'domain'
// 套件管理
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
plugins {
id "${quarkusPluginId}" version "${quarkusPluginVersion}"
}
}
// 依賴版本管理
dependencyResolutionManagement {
repositories {
mavenCentral()
}
versionCatalogs {
libs {
version('junit', '5.8.2')
library('junit-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit')
library('junit-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit')
}
}
}
在大型專案中,通常會有多個子模組,每個模組負責不同的功能或領域。這些模組可以共享某些配置,也可以有專屬的設置。
子模組結構範例:
my-project/
|-- settings.gradle
|-- build.gradle
|-- api/
| |-- build.gradle
|-- service/
|-- build.gradle
在 settings.gradle
文件中通過 include
命令來定義這些子專案:
rootProject.name = 'my-project'
include 'api', 'service'
api/build.gradle
:
plugins {
id 'java'
}
dependencies {
implementation 'io.quarkus:quarkus-resteasy'
}
service/build.gradle
:
plugins {
id 'java'
}
dependencies {
implementation 'org.hibernate:hibernate-core:5.4.30.Final'
}
這樣,Gradle 會將 api
和 service
模組納入專案的構建中,並可以在它們各自的 build.gradle
文件中進行具體的配置。
build.gradle
是 Gradle 的核心構建腳本,每個專案或子專案都會有一個 build.gradle
文件。這個文件負責定義構建邏輯、依賴管理和自定義任務。
用途:
dependencies
區塊中聲明專案的各種依賴,包括編譯時依賴、運行時依賴、測試依賴等。配置範例
// 針對所有專案的通用配置
allprojects {
apply plugin: 'java'
group = 'com.example'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '11'
targetCompatibility = '11'
repositories {
mavenCentral()
}
}
// 針對子專案的通用依賴配置
subprojects {
dependencies {
testImplementation 'junit:junit:4.13'
}
test {
useJUnitPlatform()
}
}
// 根專案的特定依賴
dependencies {
implementation 'org.apache.commons:commons-lang3:3.12.0'
}
// 自定義任務
task hello {
doLast {
println 'Hello from root project'
}
}
子專案的 build.gradle
範例:
plugins {
id 'io.quarkus'
}
dependencies {
implementation 'io.quarkus:quarkus-resteasy'
// 子專案特定的依賴
}
// 定義子專案的自定義任務
task buildApi {
doLast {
println 'Building API module...'
}
}